// Decompiled by Jad v1.5.7g. Copyright 2000 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/SiliconValley/Bridge/8617/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi 
// Source File Name:   Tuple.java

package lights.dracots;

import java.io.*;
import java.util.Vector;
import lights.interfaces.IField;
import lights.interfaces.ITuple;

// Referenced classes of package lights:
//            Field

public class Tuple implements ITuple, Serializable {

	private static final long serialVersionUID = 654845967532611182L;
	
	protected Vector _fields;
	
	private transient byte serForm[];

	public Tuple() {
		_fields = null;
		_fields = new Vector();
	}

	public ITuple add(IField field) {
		_fields.addElement(field);
		return this;
	}

	public ITuple set(IField field, int index) {
		_fields.setElementAt(field, index);
		return this;
	}

	public IField get(int index) {
		return (IField) _fields.elementAt(index);
	}

	public ITuple insertAt(IField field, int index) {
		_fields.insertElementAt(field, index);
		return this;
	}

	public ITuple removeAt(int index) {
		_fields.remove(index);
		return this;
	}

	public IField[] getFields() {
		IField ret[] = new Field[_fields.size()];
		_fields.copyInto(ret);
		return ret;
	}

	public int length() {
		return _fields.size();
	}

	/**
	 * We modify this method to allow a wild card "_*_", used to match multiple
	 * fields.
	 * 
	 * @author Xing Jiankuan
	 */
	public boolean matches(ITuple tuple) {
		// an empty tuple can match any tuple
		if (_fields.size() == 0 || tuple.length() == 0)
			return true;
		
		boolean matching = true;
		int fieldsCount = 0;
		// get the last field
		Field lastField1 = (Field) _fields.get(_fields.size() - 1);
		Field lastField2 = (Field) tuple.get(tuple.length() - 1);
		
		if(!lastField1.equals(Field.MATCH_ALL_FIELD) && 
				lastField2.equals(Field.MATCH_ALL_FIELD)) {
			//swap the match
			return tuple.matches(this);
		}

		if (lastField1.equals(Field.MATCH_ALL_FIELD)) {
			if (_fields.size() == 1)
				return true; // only a wildcard field can match anything
			if (tuple.length() < _fields.size() - 1)
				return false; // not long enough
			fieldsCount = _fields.size() - 1;
		} else {
			fieldsCount = _fields.size();
			matching = _fields.size() == tuple.length();
		}

		for (int i = 0; matching && i < fieldsCount; i++)
			matching = matching
					&& ((IField) _fields.elementAt(i)).matches(tuple.get(i));

		return matching;
	}

	public String toString() {
		String result = null;
		for (int i = 0; i < length(); i++)
			result = result != null ? result + ", " + get(i).toString()
					: get(i).toString();

		return "<" + result + ">";
	}

	protected byte[] getSerializedForm() {
		byte result[] = (byte[]) null;
		try {
			ByteArrayOutputStream bs = new ByteArrayOutputStream();
			ObjectOutputStream os = new ObjectOutputStream(bs);
			os.writeObject(this);
			os.flush();
			os.close();
			bs.close();
			result = bs.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}

	protected void setSerializedForm(byte serForm[]) {
		this.serForm = serForm;
	}

	protected ITuple createDeepCopy() {
		return deserialize(getSerializedForm());
	}

	protected ITuple getDeepCopy() {
		return deserialize(serForm);
	}

	protected static ITuple deserialize(byte serForm[]) {
		ITuple result = null;
		try {
			ObjectInputStream is = new ObjectInputStream(
					new ByteArrayInputStream(serForm));
			result = (ITuple) is.readObject();
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return result;
	}
}
